﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Input;
using System.IO;
using Microsoft.Practices.Unity;
using ContestMeter.Common;
using System.Windows.Threading;
using System.Security.Permissions;
using System.Threading;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows.Data;
using Microsoft.Win32;
using System.Windows;
using ContestMeter.UI;
using ContestMeter.Participants.UI.Properties;

namespace ContestMeter.Participants.UI
{
    public class MainViewModel : ViewModel<MainView>
    {
        [Dependency]
        public IFileSystem FileSystem { get; set; }

        private Participant _participant;
        public Participant Participant
        {
            get
            {
                if (_participant == null)
                {
                    string partPath = FileSystem.Combine(Configuration.Site, 
                        FtpUtilities.GetLocalIP4().ToString());
                    _participant = Participant.Load(FileSystem, Settings.Default.SolutionFolder);
                }
                return _participant;
            }
            //set
            //{
            //    if (_participant != value)
            //    {
            //        _participant = value;
            //        OnPropertyChanged("Participant");
            //    }
            //}
        }

        [Dependency]
        public IConfiguration Configuration { get; set; }

        ICollectionView _view;
        public ICollectionView SolutionsView
        {
            get
            {
                if (_view == null)
                {
                    _view = CollectionViewSource.GetDefaultView(Participant.Solutions);
                    _view.CurrentChanged += (s,e)=>OnCurrentChanged();
                }

                return _view;
            }
        }

        public void OnCurrentChanged()
        {
            if (_deleteCommand != null)
            {
                _deleteCommand.RaiseCanExecuteChanged();
            }
        }

        public Solution Current
        {
            get
            {
                return SolutionsView.CurrentItem as Solution;
            }
        }

        #region ChangeName Command
        private DelegateCommand<object> _changenameCommand;
        public ICommand ChangeNameCommand
        {
            get
            {
                if (_changenameCommand == null)
                {
                    _changenameCommand = new DelegateCommand<object>(x => ChangeName(), x => CanChangeName());
                }
                return _changenameCommand;
            }
        }



        protected virtual void ChangeNameCanExecuteChanged()
        {
            if (_changenameCommand != null)
            {
                _changenameCommand.RaiseCanExecuteChanged();
            }
        }
        #endregion

        #region Refresh Command
        private DelegateCommand<object> _refreshCommand;
        public ICommand RefreshCommand
        {
            get
            {
                if (_refreshCommand == null)
                {
                    _refreshCommand = new DelegateCommand<object>(x => Refresh(), x => CanRefresh());
                }
                return _refreshCommand;
            }
        }
        protected virtual void RefreshCanExecuteChanged()
        {
            if (_refreshCommand != null)
            {
                _refreshCommand.RaiseCanExecuteChanged();
            }
        }
        #endregion

        #region Check Command
        private DelegateCommand<Solution> _checkCommand;
        public ICommand CheckCommand
        {
            get
            {
                if (_checkCommand == null)
                {
                    _checkCommand = new DelegateCommand<Solution>(x => BeginCheck(x), x => CanCheck());
                }
                return _checkCommand;
            }
        }
        protected virtual void CheckCanExecuteChanged()
        {
            if (_checkCommand != null)
            {
                _checkCommand.RaiseCanExecuteChanged();
            }
        }
        protected virtual void BeginCheck(Solution solution)
        {
            IsBusy = true;
            CheckCanExecuteChanged();
            new Action<Solution>(Check).BeginInvoke(solution, CheckCompletedInWorkerThread, null);
        }
        private void CheckCompletedInWorkerThread(IAsyncResult result)
        {
            View.Dispatcher.Invoke(new Action<IAsyncResult>(CheckCompleted), result);
        }
        protected virtual void CheckCompleted(IAsyncResult result)
        {
            IsBusy = false;
            CheckCanExecuteChanged();
        }
        #endregion


        #region Delete Command
        private DelegateCommand<object> _deleteCommand;
        public ICommand DeleteCommand
        {
            get
            {
                if (_deleteCommand == null)
                {
                    _deleteCommand = new DelegateCommand<object>(x => Delete(), x => true);
                }
                return _deleteCommand;
            }
        }

        #endregion


        #region Add Command
        private DelegateCommand<object> _addCommand;
        public ICommand AddCommand
        {
            get
            {
                if (_addCommand == null)
                {
                    _addCommand = new DelegateCommand<object>(x => Add(), x => CanAdd());
                }
                return _addCommand;
            }
        }
        #endregion
        public void Add()
        {
            var viewModel = Container.Resolve<AddSolutionViewModel>();
            viewModel.Participant = Participant;
            viewModel.View.ShowDialog();
        }

        public bool CanAdd()
        {
            return !IsBusy;
        }

        #region Upload Command
        private DelegateCommand<object> _uploadCommand;
        public ICommand UploadCommand
        {
            get
            {
                if (_uploadCommand == null)
                {
                    _uploadCommand = new DelegateCommand<object>(x => Upload(), x => true);
                }
                return _uploadCommand;
            }
        }
        protected virtual void UploadCanExecuteChanged()
        {
            if (_uploadCommand != null)
            {
                _uploadCommand.RaiseCanExecuteChanged();
            }
        }
        #endregion
        protected virtual void Upload()
        {
            if (Participant != null && Participant.Solutions != null && Participant.IsValid)
            {
                foreach (var solution in Participant.Solutions)
                {
                    if (solution.Configuration == null)
                    {
                        solution.Configuration = Configuration;
                    }
                    try
                    {
                        solution.Upload();
                    }
                    catch (Exception e)
                    {
                        MessageBox.Show(e.Message);
                    }
                }
            }
            else
            {
                MessageBox.Show("Необходимо заполнить данные участника!");
            }
        }

        public void Delete()
        {
            if (!IsBusy && Current != null && Participant != null)
            {
                Participant.Solutions.Remove(Current);
                Participant.Save(Configuration.SolutionsFolder);
            }
        }

        protected virtual void Check(Solution solution)
        {
            solution.Configuration = Configuration;
            try
            {
                solution.Upload();
                solution.Check(LocalFolder, Configuration.SolutionsFolder);
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message);
            }

        }

        protected virtual bool CanCheck()
        {
            return !IsBusy;
        }

        protected virtual void Refresh()
        {
            
            //Solutions.Clear();

            //var solutions = Participant.Discover(Configuration);

            //foreach (var sol in solutions)
            //{
            //    Solutions.Add(sol);
            //}
        }
        protected virtual bool CanRefresh()
        {
            return !IsBusy;
        }

        protected virtual void ChangeName()
        {
            var viewModel = Container.Resolve<ChangeNameViewModel>();
            viewModel.Participant = Participant;
            viewModel.View.ShowDialog();

            //Participant = Participant.Load(Configuration);
        }

        protected virtual bool CanChangeName()
        {
            return !IsBusy;
        }

        protected override void OnViewChanged()
        {
            base.OnViewChanged();

            if (Participant != null)
            {
                return;
            }



            if (!Participant.IsValid)
            {
                ChangeName();
            }
        }

        public static string LocalFolder
        {
            get
            {
                var folder = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Tester");

                if (!Directory.Exists(folder))
                {
                    Directory.CreateDirectory(folder);
                }

                return folder;
            }
        }



    }
}
